package com.wxy.chinamapview.gesture;

import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.RectF;
import android.graphics.Region;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.Scroller;

import com.wxy.chinamapview.model.ProvinceModel;
import com.wxy.chinamapview.view.ChinaMapView;

public class MyGestureDector {
    private Context context;
    private int mActivePointerId;
    protected float downX = 0, downY = 0;
    protected float mLastX = 0, mLastY = 0;
    private float onMoveDownY;    //移动的前一个Y坐标
    private float onMoveDownX;    //移动的前一个X坐标
    private boolean isConsume;
    private float[] matrixValues = new float[9];
    private final int INVALID_POINTER = -1;
    private Matrix matrix;
    private ChinaMapView view;//持有View用于重绘
    private OnGestureClickListener onGestureClickListener;
    private int mapWidth, mapHeight;//map初始宽度和高度
    private int viewWidth, viewHeight;//map初始宽度和高度
    private ChinaMapView.onPromiseParentTouchListener onPromiseParentTouchListener;

    public void setOnPromiseParentTouchListener(ChinaMapView.onPromiseParentTouchListener onPromiseParentTouchListener) {
        this.onPromiseParentTouchListener = onPromiseParentTouchListener;
    }

    public MyGestureDector(Context context, ChinaMapView view, Matrix matrix, OnGestureClickListener onGestureClickListener) {
        this.context = context;
        this.matrix = matrix;
        this.onGestureClickListener = onGestureClickListener;
        this.view = view;
    }

    public void setMapWidthAndHeight(int mapWidth, int mapHeight) {
        this.mapWidth = mapWidth;
        this.mapHeight = mapHeight;
    }

    public void setViewWidthAndHeight(int viewWidth, int viewHeight) {
        this.viewWidth = viewWidth;
        this.viewHeight = viewHeight;
    }

    public boolean onTouchEvent(boolean enableScroll, MotionEvent event) {

        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                mActivePointerId = event.getPointerId(0);
                downX = event.getX();
                downY = event.getY();
                onMoveDownX = event.getX();
                onMoveDownY = event.getY();
                isConsume = view.consumeEvent(enableScroll,event);
                if (onPromiseParentTouchListener != null) {
                    if (isConsume) {
                        view.getParent().requestDisallowInterceptTouchEvent(true);
                        onPromiseParentTouchListener.onPromiseTouch(false);
                    } else {
                        view.getParent().requestDisallowInterceptTouchEvent(false);
                        onPromiseParentTouchListener.onPromiseTouch(true);
                    }
                }
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                //如果有新的手指按下，就直接把它当作当前活跃的指针
                final int index = event.getActionIndex();
                mActivePointerId = event.getPointerId(index);
                //并且刷新上一次记录的旧坐标值
                downX = event.getX(index);
                downY = event.getY(index);
                onMoveDownX = event.getX(index);
                onMoveDownY = event.getY(index);
                break;
            case MotionEvent.ACTION_POINTER_UP:
                onSecondaryPointerUp(event);
                break;
            case MotionEvent.ACTION_MOVE:
                if (!isConsume) {
                    break;
                }
                int activePointerIndex = event.findPointerIndex(mActivePointerId);
                if (activePointerIndex == INVALID_POINTER) {
                    break;
                }
                float dx = event.getX(activePointerIndex) - onMoveDownX;
                float dy = event.getY(activePointerIndex) - onMoveDownY;
                matrix.getValues(matrixValues);
                if (mapHeight != 0 && mapWidth != 0 && viewHeight != 0 && viewWidth != 0) {
                    RectF rectF = getMatrixRectF();
                    //其实，因为精度问题，只会有这两种情况，(float)viewWidth/(float)viewHeight和(float)mapWidth/(float)mapHeight始终不相等。
                    //即view的长宽比和map缩放后的长宽比基本一致的情况，按照下面任何一种情况都可以处理
                    // (float)viewWidth/(float)viewHeight+"="+(float)mapWidth/(float)mapHeight);
                    if ((float) viewWidth / (float) viewHeight < (float) mapWidth / (float) mapHeight) {
                        if (rectF.left + dx >= viewWidth / 2) {
                            dx = viewWidth / 2 - rectF.left;
                        }
                        if (rectF.right + dx <= viewWidth / 2) {
                            dx = viewWidth / 2 - rectF.right;
                        }
                        if (rectF.bottom - (viewHeight - mapHeight) * getScale() + dy <= mapHeight / 2) {
                            dy = mapHeight / 2 - (rectF.bottom - (viewHeight - mapHeight) * getScale());
                        }
                        if (rectF.top + dy >= viewHeight - mapHeight / 2) {
                            dy = viewHeight - mapHeight / 2 - rectF.top;
                        }
                    } else {
                        if (rectF.top + dy >= viewHeight / 2) {
                            dy = viewHeight / 2 - rectF.top;
                        }
                        if (rectF.bottom + dy <= viewHeight / 2) {
                            dy = viewHeight / 2 - rectF.bottom;
                        }
                        if (rectF.left + dx >= viewWidth - mapWidth / 2) {
                            dx = viewWidth - mapWidth / 2 - rectF.left;
                        }
                        if (rectF.right - (viewWidth - mapWidth) * getScale() + dx <= mapWidth / 2) {
                            dx = mapWidth / 2 - (rectF.right - (viewWidth - mapWidth) * getScale());
                        }
                    }
                }
                matrix.postTranslate(dx, dy);
                view.invalidate();
                onMoveDownX = event.getX(activePointerIndex);
                onMoveDownY = event.getY(activePointerIndex);
                break;
            case MotionEvent.ACTION_CANCEL:
                mActivePointerId = INVALID_POINTER;
                if (onPromiseParentTouchListener != null) {
                    onPromiseParentTouchListener.onPromiseTouch(true);
                }
                break;
            case MotionEvent.ACTION_UP:
                mActivePointerId = INVALID_POINTER;
                float clickX = downX - event.getX();
                float clickY = downY - event.getY();
                if (Math.abs(clickX) <= ViewConfiguration.get(context).getScaledTouchSlop() &&
                        Math.abs(clickY) <= ViewConfiguration.get(context).getScaledTouchSlop()) {
                    if (onGestureClickListener != null) {
                        RectF rectF = getMatrixRectF();
                        //把坐标换算到初始坐标系，用于判断点击坐标是否在某个省份内
                        PointF pf = new PointF((event.getX() - rectF.left) / getScale()
                                , (event.getY() - rectF.top) / getScale());
                        onGestureClickListener.onClick((int) pf.x, (int) pf.y);

                    }
                }
                if (onPromiseParentTouchListener != null) {
                    onPromiseParentTouchListener.onPromiseTouch(true);
                }
                break;
        }
        if (mActivePointerId != INVALID_POINTER) {
            mLastX = event.getX(event.findPointerIndex(mActivePointerId));
            mLastY = event.getY(event.findPointerIndex(mActivePointerId));
        } else {
            mLastX = event.getX();
            mLastY = event.getY();
        }

        return true;
    }

    private void onSecondaryPointerUp(MotionEvent ev) {
        int pointerIndex = ev.getActionIndex();
        int pointerId = ev.getPointerId(pointerIndex);
        //如果抬起的那根手指，刚好是当前活跃的手指，那么
        if (pointerId == mActivePointerId) {
            //另选一根手指，并把它标记为活跃（皇帝驾崩，太子登基）
            int newPointerIndex = pointerIndex == 0 ? 1 : 0;
            mActivePointerId = ev.getPointerId(newPointerIndex);
            //把上一次记录的坐标，更新为新手指的当前坐标
            downX = ev.getX(newPointerIndex);
            downY = ev.getY(newPointerIndex);
            onMoveDownX = ev.getX(newPointerIndex);
            onMoveDownY = ev.getY(newPointerIndex);
        }

    }

    public interface OnGestureClickListener {
        void onClick(int x, int y);
    }

    private RectF getMatrixRectF() {
        RectF rect = new RectF();
        rect.set(0, 0, viewWidth, viewHeight);
        matrix.mapRect(rect);
        return rect;
    }

    /**
     * 获得当前的缩放比例
     *
     * @return
     */
    public float getScale() {
        matrix.getValues(matrixValues);
        if (matrixValues[Matrix.MSCALE_X] == 0) {
            return 1;
        } else {
            return matrixValues[Matrix.MSCALE_X];
        }
    }
}
